
class Widget < MyCompositeDecorator
  attr_accessor :element, :parent

  def initialize(attrs = {})
    super()
    init_element(Element.new(:div))
  end

  def << composite
    if child
      child << composite
    else
      super
    end
  end

  def children
    child.children
  end

  def children= ch
    child.children= ch
  end

  def to_s
    child.to_s
  end

  def remove composite
    self.children -= [composite]
  end

#  def visit &block
#    element.visit &block
#  end
#
  def dump
    element.dump
  end

  def recieve data
    element.recieve data
  end

  def element
    child || init_element()
  end

  def init_element element = Element.new(:div)
    self.child = element
    @primary_class_names = []
    @secondary_class_names ||= []
    @class_names = []
    if element.class_name
      add_primary_class element.class_name
    end
    add_primary_class self.class.to_s.split('::').last
  end

  def add_primary_class name
    @primary_class_names << name
    class_name
  end

  def add_class name
    @class_names << name
    class_name
  end

  def set_primary_classes classes
    @primary_class_names = classes
    class_name
  end

  def add_secondary_class sc
    @secondary_class_names << sc
    class_name
  end

  def class_name
    element.set('class', render_class_name)
  end

#  def to_s
#    if !child
#      raise 'No element set! Should have called "init_element" with element during initialize.'
#    end
#    child.to_s
#  end

#  def append_child *a
#    << *a
#  end

#  def self  <<widget
#    element.append_child widget
#    @children << widget
#    if widget.kind_of? Widget
#      widget.parent = self
#    end
#    widget
#  end

#  def remove child
#    element.remove child
#    @children = @children - [child]
#    child.parent = nil
#    child
#  end

  def id
    element.id ||= Element.generate_id
  end

private

  def render_class_name
    (@primary_class_names.map { |name|
      ([name] +
        @secondary_class_names.map { |s_name|
          name+'-'+s_name
        }
      ).join(' ')
    }+@class_names).join(' ')
  end

public

  class Test < FwTest

    class TimePanel < Widget
      def initialize
        panel = Element.new :div
        panel.append_child 'time'
        init_element(panel)
      end
    end

    def test_composite_creation
      w = TimePanel.new
      assert_equal '<div class="TimePanel">time</div>', w.to_s
    end

    def test_add_primary_class_name
      w = TimePanel.new
      w.add_primary_class 'TimePicker'
      assert_equal '<div class="TimePanel TimePicker">time</div>', w.to_s
    end

    def test_add_widget
      parent = Widget.new
      child = Widget.new
      parent << child
      assert_equal parent.children, [child]
    end

#    def test_widget_parent_set_on_add
#      parent = Widget.new
#      child = Widget.new
#      parent  << child
#      assert_equal parent, child.parent
#    end

    def test_remove_widget
      parent = Widget.new
      child = Widget.new
      parent << child
      parent.remove child
      assert_equal [], parent.children
    end

    def test_widget_parent_set_nil_on_remove
      parent = Widget.new
      child = Widget.new
      parent  << child
      parent.remove child
      assert_equal nil, child.parent
    end

    def test_add_one_secondary_class_to_one_primary
      w = Widget.new
      w.set_primary_classes ["Toy"]
      w.add_secondary_class "car"
      eq w.to_s, "<div class=\"Toy Toy-car\"></div>"
    end

    def test_add_one_secondary_class_to_multiple_primary
      w = Widget.new
      w.add_primary_class "Toy"
      w.add_secondary_class "car"
      eq w.to_s, "<div class=\"Widget Widget-car Toy Toy-car\"></div>"
    end

    def test_add_secondary_class_trims

    end
  end
end



class Panel < Widget

  def initialize
    init_element Element.new :div
  end

  def self add_child
    child.append_child child
  end
end



